package com.cc.visitor.controller;

import com.cc.alltype.BusinessException;
import com.cc.alltype.ResponseResult;
import com.cc.alltype.wechat.QrType;
import com.cc.alltype.wechat.SceneQRTicketRes;
import com.cc.visitor.dao.LoginQrLogMapper;
import com.cc.visitor.entity.LoginQrLog;
import com.cc.visitor.entity.wechat.CreateQrTicketReqParam;
import com.cc.visitor.service.JssdkSignatureService;
import com.cc.visitor.service.UserWeixinService;
import com.cc.visitor.utils.TemplateMsgUtils;
import com.cc.visitor.utils.WechatUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 本后台服务与微信开放平台的通信接口
 * @author chanchaw
 * @create 2024-09-20 8:19
 */
@CrossOrigin
@RestController
@RequestMapping("/wxmp")
public class WxmpController {
    @Autowired
    private TemplateMsgUtils templateMsgUtils;
    @Autowired
    private LoginQrLogMapper loginQrLogMapper;
    @Autowired
    private UserWeixinService userWeixinService;
    private static final Logger logger = LoggerFactory.getLogger("wxmp");
    @Autowired
    private WechatUtils wechatUtils;
    @Autowired
    private JssdkSignatureService jssdkSignatureService;

    @PostMapping("/pushArrived/{visitId}")
    public ResponseResult pushArrived(@PathVariable Integer visitId){
        templateMsgUtils.pushArrived(visitId);
        return ResponseResult.ok("已推送pushArrived给受访者");
    }

    @PostMapping("/mp")
    public void handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
        logger.info("微信服务器请求开发者微信后台");
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        String resXML = wechatUtils.getResponse(request.getInputStream());
        PrintWriter out = response.getWriter();
        out.print(resXML);
        out.flush();
        out.close();
    }

    /**
     * 2024年11月9日 16:01:24，微信后台请求开发者服务器测试通信用
     * 在微信管理后台设置通信路径并保存后会立即请求本接口验证开发者服务器是否可用
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/mp")
    public String checkSignature(HttpServletRequest request, HttpServletResponse response){
        String signature = request.getParameter("signature");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");
        String echostr = request.getParameter("echostr");

        String tip = "signature = " + signature + ",nonce = " + nonce + ", timestamp = " + timestamp + ", echostr = " + echostr;
        logger.info(tip,"微信服务器get请求验证本后台服务的合法性");

        if(WechatUtils.checkServer(timestamp,nonce,signature)){
            PrintWriter out = null;
            try {
                out = response.getWriter();
                out.print(echostr);
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            logger.info("微信服务器请求验证身份成功");
        }else{
            logger.info("微信服务器请求验证身份失败");
        }
        return null;
    }

    /**
     * 微信小程序调用
     * 用户 openId,unionId 等
     * @param code 小程序通过 wx.login() 获取的 code
     * @return
     * @throws JsonProcessingException
     */
    @PostMapping("/getUserProfileMini/{code}")
    public ResponseResult getUserProfileMini(@PathVariable String code) throws JsonProcessingException {
        return ResponseResult.ok(wechatUtils.getUserProfile(code));
    }

    /**
     * 微信小程序调用
     * 先查询获取用户 openId 再查询本项目后台数据库中用户信息
     * @param code 小程序通过 wx.login() 获取的 code
     * @return
     * @throws JsonProcessingException
     */
    @PostMapping("/getUserWeixinMini/{code}")
    public ResponseResult getUserWeixinMini(@PathVariable String code) throws JsonProcessingException {
        return ResponseResult.ok(wechatUtils.getUserWeixin(code));
    }

    @PostMapping("/getUserWeixin8MiniId/{miniId}")
    public ResponseResult getUserWeixin8MiniId(@PathVariable String miniId) throws JsonProcessingException {
        return ResponseResult.ok(userWeixinService.select8MiniId(miniId));
    }

    /**
     * 2024年12月11日 12:53:46 请求二维码 ticket
     * 传入参数 CreateQrTicketReqParam 定义了临时/永久类型的二维码
     * 以及二维码的用途。请求微信服务号：showa精工
     * @param param 请求二维码的类型的参数实例
     * @return
     * @throws JsonProcessingException
     */
    @PostMapping("/sceneQRTicket")
    public ResponseResult getSceneQRTicketTemp(@RequestBody CreateQrTicketReqParam param) throws JsonProcessingException {
        Integer permanent = param.getPermanent();
        QrType qrTypeEnum = QrType.ofId(permanent);
        return ResponseResult.ok("成功", wechatUtils.getQRTicket(qrTypeEnum,param.getSceneFull()));
    }

    /**
     * 请求微信服务器获取二维码
     * 1. 参数 CreateQrTicketReqParam 对象会将多个属性拼接为一个完整的二维码场景值
     *      即二维码场景值中包含了本二维码：是否永久，二维码用途（场景值的前面两个数据）
     *      所以请求永久普通访客关注用二维码的传入参数是：{"permanent":1,"type":0,"sceneData":"10"}
     *      请求web端用于登录的二维码的传入参数是：{"permanent":0,"type":3,"sceneData":UUID}
     * 2. 请求微信服务器响应来的用于替换二维码的 ticket 需要拼接一个URL，才能在前面显示出二维码
     * @param param
     * @return 属性 data 中是二维码图片的URL地址
     * @throws JsonProcessingException
     */
    @PostMapping("/qrCodeUrl")
    public ResponseResult getQrCodeUrl(@RequestBody CreateQrTicketReqParam param) throws JsonProcessingException {
        Integer permanent = param.getPermanent();
        QrType qrTypeEnum = QrType.ofId(permanent);
        SceneQRTicketRes qrTicket = wechatUtils.getQRTicket(qrTypeEnum, param.getSceneFull());
        String ticket = Optional.ofNullable(qrTicket.getTicket()).orElse("");
        if(ticket.length() == 0) throw new BusinessException("没有获取到用于兑换二维码的票据。");
        String encodedTicket = URLEncoder.encode(ticket);
        String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + encodedTicket;

        // 写入登录二维码日志表,CreateQrTicketReqParam.sceneData 是前端发送来的 UUID
        LoginQrLog loginQrLog = LoginQrLog.builder().ticket(ticket).sceneStr(param.getSceneData()).ticketTime(LocalDateTime.now()).build();
        //LoginQrLog loginQrLog = LoginQrLog.builder().ticket(ticket).sceneStr(param.getSceneData()).build();
        loginQrLogMapper.insertSelective(loginQrLog);
        return ResponseResult.ok("data属性中是二维码URL", url);
    }
    @PostMapping("/openId")
    public ResponseResult getOpenId8Code(@RequestBody String code){
        return ResponseResult.ok("", WechatUtils.getMpOpenId8Code(code));
    }

    /**
     * 使用当前有效的 jsapi_ticket 构建 js-sdk signature 并返回
     * @param url
     * @return
     */
    @PostMapping("/signature")
    public ResponseResult signature(@RequestBody String url){
        return ResponseResult.ok("", jssdkSignatureService.getSignature(url));
    }

    @PostMapping("/pushDevAlert")
    public ResponseResult pushDevAlert(@RequestBody List<Object> msgList) throws Exception {
        String s = templateMsgUtils.pushDevAlert(msgList);
        return ResponseResult.ok("已推送的微信用户", s);
    }
}
